#include "productbrowseservice.h"
#include <QDebug>
#include <QLocale>

/**
 * @brief 构造函数：初始化产品浏览服务
 * @param productDao 数据访问对象（由外部注入，服务层不负责生命周期管理）
 * @param parent 父对象
 * 注：初始化时加载分类缓存，减少后续数据库访问
 */
ProductBrowseService::ProductBrowseService(ProductDAO* productDao, QObject *parent)
    : QObject(parent), m_productDao(productDao)
{
    // 校验空处理：避免后续操作出现空指针异常
    if (!m_productDao) {
        qWarning() << "ProductBrowseService: ProductDAO is null!";
        return;
    }

    // 预加载分类缓存，提升后续查询性能
    loadCategoryCache();
}

/**
 * @brief 析构函数
 * 注：ProductDAO由外部管理，此处不做删除操作，避免二次释放
 */
ProductBrowseService::~ProductBrowseService()
{
    // ProductDAO由外部管理，不在此处删除
}

/**
 * @brief 获取所有商品及对应的分类名称
 * @return 包含商品信息和分类名称的集合
 * 逻辑：1. 从DAO获取原始商品数据 2. 为每个商品补充分类名称 3. 触发数据加载完成信号
 */
QVector<QMap<QString, QVariant>> ProductBrowseService::getAllProductsWithCategory()
{
    // 前置校验：确保数据访问层可用
    if (!m_productDao) {
        emit errorOccurred("数据访问层未初始化");
        return QVector<QMap<QString, QVariant>>();
    }

    try {
        // 从数据层获取所有商品
        QVector<QMap<QString, QVariant>> products = m_productDao->getAllProducts();

        // 为每个商品添加分类名称（缓存中获取，减少数据库查询）
        for (auto& product : products) {
            int categoryId = product["category_id"].toInt();
            product["category_name"] = getCategoryName(categoryId);
        }

        // 通知UI层数据加载完成
        emit dataLoaded();
        return products;
    } catch (const std::exception& e) {
        // 异常捕获：将底层错误信息通过信号传递给UI
        emit errorOccurred(QString("获取商品数据失败: %1").arg(e.what()));
        return QVector<QMap<QString, QVariant>>();
    }
}

/**
 * @brief 按分类ID获取商品列表
 * @param categoryId 分类ID
 * @return 该分类下的商品集合（已补充分类名称）
 */
QVector<QMap<QString, QVariant>> ProductBrowseService::getProductsByCategory(int categoryId)
{
    if (!m_productDao) {
        emit errorOccurred("数据访问层未初始化");
        return QVector<QMap<QString, QVariant>>();
    }

    try {
        // 按分类ID查询商品
        QVector<QMap<QString, QVariant>> products = m_productDao->getProductsByCategory(categoryId);

        // 统一设置分类名称（一次获取，避免循环中重复查询）
        QString categoryName = getCategoryName(categoryId);
        for (auto& product : products) {
            product["category_name"] = categoryName;
        }

        return products;
    } catch (const std::exception& e) {
        emit errorOccurred(QString("获取分类商品失败: %1").arg(e.what()));
        return QVector<QMap<QString, QVariant>>();
    }
}

/**
 * @brief 按名称搜索商品
 * @param name 搜索关键词（支持模糊搜索）
 * @return 匹配的商品集合（空关键词时返回所有商品）
 */
QVector<QMap<QString, QVariant>> ProductBrowseService::searchProductsByName(const QString& name)
{
    if (!m_productDao) {
        emit errorOccurred("数据访问层未初始化");
        return QVector<QMap<QString, QVariant>>();
    }

    // 空搜索词处理：返回全部商品
    if (name.trimmed().isEmpty()) {
        return getAllProductsWithCategory();
    }

    try {
        // 按名称搜索商品
        QVector<QMap<QString, QVariant>> products = m_productDao->searchProductsByName(name);

        // 补充分类名称
        for (auto& product : products) {
            int categoryId = product["category_id"].toInt();
            product["category_name"] = getCategoryName(categoryId);
        }

        return products;
    } catch (const std::exception& e) {
        emit errorOccurred(QString("搜索商品失败: %1").arg(e.what()));
        return QVector<QMap<QString, QVariant>>();
    }
}

/**
 * @brief 获取商品详细信息
 * @param productId 商品ID
 * @return 包含详细信息的商品对象（含分类名称）
 */
QMap<QString, QVariant> ProductBrowseService::getProductDetailById(int productId)
{
    if (!m_productDao) {
        emit errorOccurred("数据访问层未初始化");
        return QMap<QString, QVariant>();
    }

    try {
        // 获取单个商品详情
        QMap<QString, QVariant> product = m_productDao->getProductById(productId);

        // 补充分类名称（仅当商品存在时）
        if (!product.isEmpty()) {
            int categoryId = product["category_id"].toInt();
            product["category_name"] = getCategoryName(categoryId);
        }

        return product;
    } catch (const std::exception& e) {
        emit errorOccurred(QString("获取商品详情失败: %1").arg(e.what()));
        return QMap<QString, QVariant>();
    }
}

/**
 * @brief 获取所有商品分类
 * @return 分类集合
 */
QVector<QMap<QString, QVariant>> ProductBrowseService::getAllCategories()
{
    if (!m_productDao) {
        emit errorOccurred("数据访问层未初始化");
        return QVector<QMap<QString, QVariant>>();
    }

    try {
        return m_productDao->getAllCategories();
    } catch (const std::exception& e) {
        emit errorOccurred(QString("获取分类信息失败: %1").arg(e.what()));
        return QVector<QMap<QString, QVariant>>();
    }
}

/**
 * @brief 获取各分类下的商品数量统计
 * @return 键为分类ID，值为商品数量的映射
 */
QMap<int, int> ProductBrowseService::getCategoryStatistics()
{
    if (!m_productDao) {
        emit errorOccurred("数据访问层未初始化");
        return QMap<int, int>();
    }

    try {
        return m_productDao->getCategoryStatistics();
    } catch (const std::exception& e) {
        emit errorOccurred(QString("获取分类统计失败: %1").arg(e.what()));
        return QMap<int, int>();
    }
}

/**
 * @brief 格式化商品信息为易读字符串
 * @param product 商品数据
 * @return 格式化后的字符串（含 emoji 标识提升可读性）
 * 注：包含库存状态判断（缺货/库存不足/充足）
 */
QString ProductBrowseService::formatProductInfo(const QMap<QString, QVariant>& product)
{
    if (product.isEmpty()) {
        return "❌ 商品信息不完整";
    }

    QString info;
    info += QString("📦 商品名称: %1\n\n").arg(product["product_name"].toString());
    info += QString("📏 规格: %1\n").arg(product["specification"].toString());
    info += QString("🎨 颜色: %1\n").arg(product["color"].toString());
    info += QString("🏢 供应商: %1\n\n").arg(product["supplier"].toString());

    info += QString("💰 价格信息:\n");
    info += QString("  • 采购价: %1\n").arg(formatPrice(product["purchase_price"].toDouble()));
    info += QString("  • 零售价: %1\n\n").arg(formatPrice(product["selling_price"].toDouble()));

    info += QString("📊 库存信息:\n");
    int stockQuantity = product["stock_quantity"].toInt();
    QString stockStatus;
    // 库存状态判断逻辑
    if (stockQuantity <= 0) {
        stockStatus = "❌ 缺货";
    } else if (stockQuantity <= 10) {
        stockStatus = "⚠️ 库存不足";
    } else {
        stockStatus = "✅ 库存充足";
    }
    info += QString("  • 库存数量: %1 件 (%2)\n\n").arg(stockQuantity).arg(stockStatus);

    info += QString("📂 分类: %1\n").arg(product["category_name"].toString());
    info += QString("💳 会员折扣: %1\n").arg(product["allow_member_discount"].toBool() ? "✅ 支持" : "❌ 不支持");
    info += QString("📅 创建时间: %1").arg(product["create_time"].toDateTime().toString("yyyy-MM-dd hh:mm:ss"));

    return info;
}

/**
 * @brief 格式化价格为中文货币格式
 * @param price 价格数值
 * @return 形如 "¥123.45" 的字符串
 */
QString ProductBrowseService::formatPrice(double price)
{
    // 使用中文区域设置，确保价格格式符合本地习惯（保留两位小数）
    return QString("¥%1").arg(QLocale(QLocale::Chinese).toString(price, 'f', 2));
}

/**
 * @brief 判断商品是否支持会员折扣
 * @param productId 商品ID
 * @return 支持返回true，否则返回false
 */
bool ProductBrowseService::isDiscountAllowed(int productId)
{
    QMap<QString, QVariant> product = getProductDetailById(productId);
    return product["allow_member_discount"].toBool();
}

/**
 * @brief 从缓存获取分类名称
 * @param categoryId 分类ID
 * @return 分类名称（缓存未命中时尝试重新加载缓存）
 */
QString ProductBrowseService::getCategoryName(int categoryId)
{
    // 优先从缓存获取，减少数据库访问
    if (m_categoryCache.contains(categoryId)) {
        return m_categoryCache[categoryId];
    }

    // 缓存未命中时重新加载缓存（容错处理）
    loadCategoryCache();

    // 仍未获取到时返回默认值
    return m_categoryCache.value(categoryId, "未知分类");
}

/**
 * @brief 加载分类缓存（内部使用）
 * 功能：从数据库获取所有分类，存储到内存缓存中
 */
void ProductBrowseService::loadCategoryCache()
{
    if (!m_productDao) {
        return;
    }

    try {
        // 从数据库获取所有分类
        QVector<QMap<QString, QVariant>> categories = m_productDao->getAllCategories();
        m_categoryCache.clear(); // 先清空旧缓存

        // 构建ID-名称映射（缓存核心数据）
        for (const auto& category : categories) {
            int id = category["category_id"].toInt();
            QString name = category["category_name"].toString();
            m_categoryCache[id] = name;
        }
    } catch (const std::exception& e) {
        qWarning() << "Failed to load category cache:" << e.what();
    }
}
